from flask import Flask, render_template,request,session,g,redirect,url_for,send_file
from src.setting import TEMPLATES,STATIC_FOLDER,Tool
from src.models import user,videoModel
from src.cache import ModelCache

# Flask启动web项目 模板文件路径配置 静态资源路径配置
app = Flask(__name__,template_folder=TEMPLATES['DIRS'],static_folder=STATIC_FOLDER)
app.secret_key = 'huxiaoting'
login_urls=['/my','/add','/edit']
# 运行开始前的装饰器
@app.before_request
def before_request_func():
    if 'user' in session:
        g.login_info = {
            'username':session['user'],
        }
    elif request.path in login_urls:
        g.tip = '请先登录'
        return redirect(url_for('login'))
        
@app.context_processor
def inject_data():
    data = {
        "login":g.login_info if hasattr(g,"login_info") else None,
        "tip":g.tip if hasattr(g,"tip") else None
    }
    return dict(data)
# 主页面
@app.route('/')
def index():   
    videolist=[]
    vtypes = []
    try:
        # videolist = list(videoModel.find()) # 获取所有的视频数据
        videolist = ModelCache.getVList() # 通过redis去获取数据
        vtypes = set([v['vtype'] for v in videolist]) # 获取视频数据中的类型
    except Exception as err:
        print(f"cache:{err}")
    return render_template('index.html',videolist=videolist,vtypes=vtypes)
# 登录页面
@app.route('/login')
def login():
    return render_template('login.html',title="这里是登录页面")
# 路由地址为/login 访问login.html模板
# 路由地址为/register 访问register.html模板
@app.route('/register')
def register():
    return render_template('register.html',title="注册")

@app.route('/my')
def my():
    res = videoModel.find({'username':session['user']})
    return render_template('my.html',title="个人中心",res=res)


@app.route('/add')
def addVideo():
    return render_template('/addVideo.html',title="添加视频")

from bson import ObjectId
@app.route('/video/<vid>')
def videoId(vid):
    res = videoModel.find({'_id':ObjectId(vid)})
    return render_template("/video.html",res=res[0])

@app.route('/get_video/<vfileid>')
def getVideo(vfileid):
    try:
        # 从GridFS中检索文件  
        video_file =  videoModel.getVideo(vfileid)
        video_filename = vfileid+'.mp4'  
        response = send_file(video_file, as_attachment=True,mimetype='video/mp4',download_name=video_filename)  
        return response 
    except Exception as err:
        return str(err)
 
@app.route('/getimg/<imgid>')
def getImg(imgid):
    try:
        # 从GridFS中检索文件  
        imgfile =  videoModel.getVideo(imgid)
        imgfilename = imgid+'.jpg'  
        response = send_file(imgfile, as_attachment=True,mimetype='image/jpeg',download_name=imgfilename)  
        return response
    except Exception as err:
        return str(err) 

# api的路由地址
# @app.route('/api/register',methods=["POST",'GET'])
# def apiRegister():
#    return Tool.jsonStr(User.find())
#     # return request
@app.route('/api/register',methods=['POST','GET'])
def apiRegister():
    if request and request.method == 'POST':
        try:
            formuser = request.form['user']
            pwd = request.form['pwd']
            repwd = request.form['repwd']
            if pwd != repwd:
                raise ValueError('两次不相同')
            # ???user值必须是20位以内的英文、中文和数字 pwd必须是英文数字_
            user_id = user.insert({'user':formuser,'pwd':pwd})
            return Tool.jsonApi(200,'插入成功',data=user_id)
        except Exception as err:
            return Tool.jsonApi(500,str(err))
    else: return "请勿非法闯入"

@app.route('/api/login',methods=['POST','GET'])
def apiLogin():
    if request and request.method == 'POST':
        try:
            formuser = request.form['username']
            pwd = request.form['password']
            login_user = user.find({'user':formuser})
            if not login_user:
                raise ValueError("该账户不存在")
            if login_user[0]['pwd']!=pwd:
                raise ValueError('账号或密码错误')
            session['user']=login_user[0]['user']
            return Tool.jsonApi(200,"登录成功")
        except Exception as err:
            return Tool.jsonApi(500,str(err))
    else:
        return "请勿非法闯入"
    
import time
@app.route('/api/addVideo',methods=['GET','POST'])
def apiAddVideo():
    if request and request.method=='POST':
        try:
            vname = request.form.get('vname')
            vtype = request.form.get('vtype')
            vdesc = request.form.get('vdesc')
            vfile = request.files.get('video')
            vimg = request.files.get('image')
            # 上传文件到GridFS上，并返回file_id
            file_id = videoModel.insertFile(vfile)
            img_id = videoModel.insertFile(vimg)
            doc = {
                "vname":vname, # 视频名字
                "vtype":vtype, # 视频类型
                "vdesc":vdesc, # 视频描述
                "vfileid":file_id,# 已上传至GridFS后的file_id值
                "vimgid":img_id,
                "username":session['user'], # 上传人的用户名 本来该存id 可以尝试去改
                "uploadtime":int(time.time()) # 上传的时间戳 就是现在
            }
            video_id = videoModel.insertDoc(doc) # 插入到Mongodb的video集合中
            ModelCache.setVList()
            return Tool.jsonApi(msg="上传视频成功",data=video_id) # 成功
        except Exception as err:
            return Tool.jsonApi(500,str(err))
    else:
        return "请勿非法闯入"

@app.route('/api/delVideo',methods=['POST'])
def apiDelVideo():
    if request and request.method=='POST':
        try:
            vid = request.form.get('id')
            videoModel.delDoc({'_id':ObjectId(vid)}) # 去model.py里面添加delDoc方法
            ModelCache.setVList()
            return Tool.jsonApi(msg="删除视频成功",data=vid) # 成功
        except Exception as err:
            return Tool.jsonApi(500,f'删除视频出错：{err}')

@app.route('/logout')
def logout():
    session.clear() # 清空
    return redirect(url_for('index'))


# flask中给jinja注册strftime过滤器
@app.template_filter('strftime')
def _jinja2_filter_datetime(timeStamp, fmt=None):
    if fmt is None:
        fmt = '%Y-%m-%d %H:%M:%S'
    timeArray = time.localtime(timeStamp)
    return time.strftime(fmt, timeArray)
